home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -in_the_mag- / multitasking / feature / executive_v2.10 / sysinfo / oberon / source / uptime.mod < prev   
Text File  |  2000-03-02  |  8KB  |  292 lines

  1. (*(*
  2.  * Uptime
  3.  *
  4.  * This file is public domain.
  5.  *
  6.  * Author: Petri Nordlund <petrin@mits.mdata.fi>
  7.  *
  8.  * $Id: uptime.c 1.5 1995/10/05 12:31:31 petrin Exp petrin $
  9.  *
  10.  * Oberon-Version by Thomas Igracki (T.Igracki@Jana.berlinet.de)
  11.  *
  12.  * 20.10.96: - Recompiled for v2
  13.  *)*)
  14.  
  15. (* OberonVersion:
  16.  *
  17.  * bug: InfoData auf long-aligned bringen.
  18.  * nur wie??? Viell. statisch def. (info: d.InfoData)??
  19.  * 
  20.  * MultiUser-Teil NICHT GETESTET!! 
  21.  *)
  22.  
  23. (*
  24.  * This is a fairly complete uptime-program. The sourcecode comes from Executive
  25.  * uptime-client, it's just modified to support SysInfo.library. This program
  26.  * can be compiled for multiuser.library support to show the number of users
  27.  * currently logged in. This requires multiuser.library include-files and
  28.  * a stub-library if you are using GCC. See GCC:geninline/README.glue for
  29.  * information about how to generate the stub-library.
  30.  *)
  31.  
  32. MODULE Uptime;
  33. IMPORT
  34.   y: SYSTEM, e: Exec, d: Dos, u: Utility, 
  35.   (* $IF UseMultiUser *) mu: MultiUser, (* $END *)
  36.   si: SysInfo, rc: RealConversions;
  37.  
  38. VAR
  39.   info: si.SysInfoPtr;
  40.  
  41. PROCEDURE PutS (str: ARRAY OF CHAR); (* $CopyArrays- *)
  42. BEGIN     d.PrintF ("%s\n",y.ADR(str))
  43. END PutS;
  44.  
  45. (*
  46.  * Print system time
  47.  *)
  48. PROCEDURE GetTime();
  49. VAR
  50.    dtime  : d.DateTime;
  51.    timestr: d.DatString;
  52. BEGIN
  53.      d.DateStamp(dtime);
  54.  
  55.      dtime.format := d.formatDos;
  56.      dtime.flags := SHORTSET{};
  57.      dtime.strDay := NIL;
  58.      dtime.strDate := NIL;
  59.      dtime.strTime := y.ADR(timestr);
  60.  
  61.      IF ~d.DateToStr(dtime) THEN END;
  62.  
  63.      d.PrintF(timestr);
  64. END GetTime;
  65.  
  66.  
  67. (*
  68.  * Print number of users (from Multiuser if available)
  69.  *)
  70. PROCEDURE Users();
  71. VAR
  72.   nusers: LONGINT;
  73.   (* $IF UseMultiUser *)
  74.   numtasks: LONGINT; uids: UNTRACED POINTER TO ARRAY OF INTEGER;
  75.   task: e.TaskPtr;
  76.   (* $END *)
  77. BEGIN
  78.      nusers := 1;
  79.  
  80. (*  $IF UseMultiUser *)
  81.      IF mu.base # NIL THEN 
  82.  
  83.         e.Forbid();
  84.  
  85.         (* Count the number of tasks currently in system *)
  86.         numtasks := CountTasks();
  87.  
  88.         (* Allocate memory for each task *)
  89.         uids := e.AllocVec (numtasks*SIZE(INTEGER), LONGSET{e.memClear,e.public});
  90.         IF uids # NIL THEN
  91.  
  92.            (* Find out how many different uids there are *)
  93.  
  94.            nusers := 0;
  95.            AddUser (mu.GetTaskOwner(e.FindTask(NIL)), uids, nusers);
  96.            task := e.base.taskReady.head;
  97.            LOOP
  98.               IF task.node.succ = NIL THEN EXIT END;
  99.               AddUser (mu.GetTaskOwner(task), uids, nusers);
  100.               task := task.node.succ;
  101.            END;
  102.            task := e.base.taskWait.head;
  103.            LOOP
  104.               IF task.node.succ = NIL THEN EXIT END;
  105.               AddUser (mu.GetTaskOwner(task), uids, y.ADR(nusers));
  106.               task := task.node.succ;
  107.            END;
  108.            e.FreeVec(uids);
  109.         END;
  110.         e.Permit();
  111.      END;
  112. (* $END *)
  113.  
  114.      IF (nusers > 1) OR (nusers = 0) THEN
  115.         d.PrintF("%ld users", nusers);
  116.      ELSE
  117.         d.PrintF("%ld user",nusers);
  118.      END;
  119. END Users;
  120.  
  121.  
  122. (* $IF UseMultiUser *)
  123.  
  124. PROCEDURE AddUser(user: LONGINT; VAR uids: ARRAY OF INTEGER; VAR nusers: LONGINT);
  125. VAR
  126.    uid: LONGINT;
  127.    found: BOOLEAN;
  128.    i: LONGINT;
  129. BEGIN
  130.      IF user # 0 THEN
  131.         uid := SHORT(user); (* ??? C: uid = user>>16; *)
  132.         i := 0; 
  133.         WHILE ~found & (i<nusers) DO found := (uids[i] = uid); INC(i) END;
  134.         IF ~found THEN INC(nusers); uids[nusers] := uid END;
  135.      END;
  136. END AddUser;
  137.  
  138. PROCEDURE CountTasks(): LONGINT;
  139. VAR
  140.    i : LONGINT;
  141.    task: e.TaskPtr;
  142. BEGIN
  143.      i := 1;
  144.  
  145.      task := y.VAL(e.TaskPtr, e.SysBase.taskReady.head);
  146.      WHILE task # NIL DO task := y.VAL(e.TaskPtr, task.node.succ); INC(i); END;
  147.  
  148.      task := y.VAL(e.TaskPtr, e.SysBase.taskWait.head);
  149.      WHILE task # NIL DO task := y.VAL(e.TaskPtr, task.node.succ); INC(i); END;
  150.  
  151.      RETURN i;
  152. END CountTasks;
  153. (* $END *)
  154.  
  155. (*
  156.  * Print uptime. We use RAM:-disk creation time.
  157.  *)
  158. PROCEDURE Uptime();
  159. VAR
  160.    boottime   : LONGINT;
  161.    currenttime: LONGINT;
  162.    dtime      : d.DateTime;
  163.    lock       : d.FileLockPtr;
  164.    infodata   : d.InfoDataPtr;
  165.    ramdevice  : d.DeviceListPtr;
  166.    days, hrs, mins, hrsTmp: LONGINT;
  167. BEGIN
  168. (*
  169.  * InfoData-structure must be long word aligned. By allocating it this way,
  170.  * we can make sure it is aligned properly. GCC has a bug in it's aligned-
  171.  * attribute <sigh> so it's not possible to just use: struct InfoData infodata.
  172.  *)
  173.  
  174.      infodata := e.AllocMem (SIZE(d.InfoData), e.any);
  175.      IF infodata = NIL THEN RETURN END;
  176.  
  177.      lock := d.Lock ("RAM:", d.sharedLock);
  178.      IF lock # NIL THEN
  179.              
  180.          IF d.Info(lock, infodata^) THEN
  181.              ramdevice := infodata.volumeNode;
  182.  
  183.              boottime :=  u.SMult32(ramdevice.volumeDate.days, 86400) +
  184.                           u.SMult32(ramdevice.volumeDate.minute, 60) +
  185.                           u.SDivMod32(ramdevice.volumeDate.tick, d.ticksPerSecond);
  186.  
  187.              d.DateStamp(dtime);
  188.  
  189.              currenttime :=  u.SMult32(dtime.stamp.days, 86400) +
  190.                              u.SMult32(dtime.stamp.minute, 60) +
  191.                              u.SDivMod32(dtime.stamp.tick, d.ticksPerSecond);
  192.  
  193.              DEC(currenttime, boottime);
  194.  
  195.              IF currenttime > 0 THEN
  196.  
  197.                 (* Calculate days, hours and minutes *)
  198.                 days := currenttime DIV 86400;
  199.                 hrs := currenttime MOD 86400; hrsTmp := hrs;
  200.                 hrs := hrs DIV 3600;
  201.                 mins := (hrsTmp MOD 3600) DIV  60;
  202.  
  203.                 IF (days > 0) OR (hrs > 0) OR (mins > 0) THEN d.PrintF("up ") END;
  204.  
  205.                 IF (days > 0) THEN
  206.                    IF (days > 1) THEN
  207.                       d.PrintF("%ld days ", days);
  208.                    ELSE
  209.                       d.PrintF("%ld day ", days);
  210.                    END;
  211.                 END; (* IF days > 0 *)
  212.                 IF (hrs > 0) THEN
  213.                    d.PrintF("%ld:%02ld", hrs, mins);
  214.                 ELSE
  215.                    IF (mins > 1) OR (mins = 0) THEN
  216.                       d.PrintF("%ld mins", mins);
  217.                    ELSE
  218.                       d.PrintF("%ld min", mins);
  219.                    END
  220.                 END; (* IF hrs > 0 *)
  221.              END; (* IF currenttime > 0 *)
  222.          END; (* IF d.Info() *)
  223.          d.UnLock(lock);
  224.      END; (* IF lock # NIL *);
  225.  
  226.      e.FreeMem(infodata, SIZE(d.InfoData));
  227. END Uptime;
  228.  
  229. PROCEDURE WriteReal (r: REAL; v,n: INTEGER);
  230. VAR str: ARRAY 50 OF CHAR;
  231. BEGIN
  232.      IF rc.RealToString (r, str, v,n, FALSE) THEN d.PrintF (str) END;
  233. END WriteReal;
  234.  
  235. (*
  236.  * Print load averages
  237.  *)
  238. PROCEDURE LoadAverages();
  239. VAR
  240.    loadAvg: si.LoadAverage; (* This will be filled by GetLoadAverage() *)
  241. BEGIN
  242.      si.GetLoadAverage (info, loadAvg);
  243.      d.PrintF("load: ");
  244.  
  245.      IF info.loadAvgType = si.loadAvgFixedPnt THEN
  246.          si.GetLoadAverage(info, loadAvg);     (* Ask SysInfo.library for current load averages *)
  247.          (* Convert fixed point values to floating point values *)
  248.          IF info.loadAvgTime1 # 0 THEN
  249.             WriteReal (loadAvg.fixed.load1 / info.fScale, 1, 2)
  250.          ELSE
  251.             d.PrintF(" N/A");
  252.          END;
  253.          IF info.loadAvgTime2 # 0 THEN
  254.             WriteReal (loadAvg.fixed.load2 / info.fScale, 1, 2)
  255.          ELSE
  256.             d.PrintF(" N/A");
  257.          END;
  258.          IF info.loadAvgTime3 # 0 THEN
  259.             WriteReal (loadAvg.fixed.load3 / info.fScale, 1, 2)
  260.          ELSE
  261.             d.PrintF(" N/A");
  262.          END;
  263.      ELSE
  264.         (* Load average is not supported *)
  265.         d.PrintF("-");
  266.      END
  267. END LoadAverages;
  268.  
  269. BEGIN
  270.      IF si.base = NIL THEN d.PrintF ("Failed to open %s v%ld!\n",y.ADR(si.name),si.version); HALT(d.warn) END;
  271.  
  272.      (* Initialize SysInfo.library, this will make the connection to the
  273.       * server-process and allocate the SysInfo-structure. *)
  274.  
  275.      info := si.InitSysInfo();
  276.      IF info = NIL THEN PutS("Couldn't initialize SysInfo."); HALT(d.fail) END;
  277.  
  278.      GetTime();
  279.      d.PrintF(", ");
  280.      Uptime();
  281.      d.PrintF(", ");
  282.      Users();
  283.      d.PrintF(", ");
  284.      LoadAverages();
  285.      d.PrintF("\n");
  286.  
  287.      HALT(d.ok);
  288. CLOSE
  289.      (* Exit. Free everything. *)
  290.      IF info # NIL THEN si.FreeSysInfo(info) END;
  291. END Uptime.
  292.